home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
telecomm
/
sticpsrc.lzh
/
SOURCE.ARC
/
DIRUTIL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-04
|
26KB
|
1,157 lines
/* dirutil.c - MS-DOS directory reading routines
*
* Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
* Directory sorting by Mike Chepponis, K3MC
* adapted for ATARI ST & cleaned up by Rob Janssen, PE1CHL
* added more shell commands by PE1CHL
*/
#include <stdio.h>
#include <ctype.h>
#ifdef MSDOS
# define IS_ERROR(x) (x) == -1 /* error return from MSDOS */
# ifdef MSC
# include <sys/types.h>
# include <sys/stat.h>
# define ST_HIDDEN _A_HIDDEN /* hidden from search */
# define ST_DIRECT _A_SUBDIR /* directory */
# else
# ifdef __TURBOC__
# define ST_HIDDEN FA_HIDDEN /* Hidden from search */
# define ST_DIRECT FA_DIREC /* Directory */
# else /* AZTEC */
# include <stat.h>
# define st_mode st_attr /* what's in a name? */
# endif
# endif
#endif
#ifdef ATARI_ST
# ifdef MWC
# include <stat.h>
# include <osbind.h>
# define bdos gemdos /* Atari OS call */
# define dos(a,b,c,d,e,f) gemdos(a,d,c) /* only valid for FIND func */
# define ST_HIDDEN S_IJHID /* Hidden from search */
# define ST_DIRECT S_IJDIR /* Directory */
# endif
# ifdef __TURBOC__
# include <tos.h>
# include <ext.h>
# define ST_HIDDEN FA_HIDDEN /* Hidden from search */
# define ST_DIRECT FA_DIREC /* Directory */
# endif
# define IS_ERROR(x) (x) < 0 /* error return from gemdos */
#endif
#include "global.h"
#define SET_DTA 0x1a
#define FIND_FIRST 0x4e
#define FIND_NEXT 0x4f
struct dirent {
char rsvd[21];
char attr;
short ftime;
short fdate;
long fsize;
char fname[13];
};
#define NULLENT (struct dirent *)0
struct dirsort {
struct dirsort *prev;
struct dirsort *next;
struct dirent *direntry;
};
#define NULLSORT (struct dirsort *)0
#ifdef ATARI_ST
static char *buffer; /* buffer for filecopy */
static int bufsiz; /* size of buffer */
#endif
static char nofile[] = "No file \"%s\"\n";
extern char cantopen[];
static int cpfile(),cptodir(),filedelete(),dirremove(),
wildcard(),getarcdir();
static void dir_sort(),format_dir(),format_fname(),diskfree(),free_clist();
static void commas();
int iswild(),isdir();
char *basename();
/* Change working directory */
docd(argc,argv)
int argc;
char *argv[];
{
char dirname[128];
#ifdef MSDOS
char *getcwd();
#endif
if(argc > 1){
if(IS_ERROR(chdir(argv[1]))){
printf("Can't change directory\n");
return 1;
}
}
#ifdef MSDOS
# if (defined(MSC) || defined(__TURBOC__))
if(getcwd(dirname,sizeof(dirname)-1) != NULLCHAR){
# else
dirname[0] = '\\';
if(getcwd(dirname + 1,sizeof(dirname)-2) != NULLCHAR){
# endif
#endif
#ifdef ATARI_ST
dirname[0] = Dgetdrv() + 'A';
dirname[1] = ':';
if(Dgetpath(dirname + 2,0) == 0){
if(dirname[2] == '\0'){
dirname[2] = '\\';
dirname[3] = '\0';
}
#endif
cleanup_fname(dirname);
printf("%s\n",dirname);
}
return 0;
}
/* copy files */
docopy(argc,argv)
int argc;
char *argv[];
{
int stat;
int i;
#ifdef ATARI_ST
long maxbuf;
#endif
for (i = 1; i < argc; i++)
cleanup_fname(argv[i]);
if (iswild(argv[argc - 1])){
printf("Last arg cannot be wildcard\n");
return 1;
}
#ifdef ATARI_ST
/* On Atari ST, use a big buffer allocated from GEMDOS */
if ((maxbuf = (long) Malloc(-1L)) < 512L) /* ask maximum buffer size */
{
printf("Cannot allocate buffer\n");
return(1);
}
bufsiz = maxbuf & 32767; /* limit bufsize to safe value */
bufsiz &= ~512L; /* round down to 512-byte multiple */
if ((long) (buffer = (char *) Malloc((long) bufsiz)) < 0) {
printf("GEMDOS error during buffer allocation\n");
return(1);
}
#endif
if (!isdir(argv[argc - 1])) /* check type of destination */
{
if (argc == 3 && !iswild(argv[1])){ /* file-to-file copy */
stat = cpfile(argv[1],argv[2]);
} else {
printf("Last arg must be a directory\n");
stat = 1;
}
} else {
stat = wildcard(argc - 1,argv,cptodir,argv[argc - 1]);
}
#ifdef ATARI_ST
Mfree(buffer); /* free the buffer */
#endif
return(stat);
}
/* delete files */
dodelete(argc,argv)
int argc;
char *argv[];
{
return wildcard(argc,argv,filedelete,NULL);
}
/* List directory to console. [-/]w option selects "wide" format */
dodir(argc,argv)
int argc;
char *argv[];
{
char *path;
int full = 1;
if (argc > 1 &&
(argv[1][0] == '-' || argv[1][0] == '/') && argv[1][1] == 'w') {
full = -1;
argv++;
argc--;
}
if(argc >= 2){
path = argv[1];
} else {
path = "*.*";
}
getdir(path,full,0,stdout);
return 0;
}
/* make directories */
domkdir(argc,argv)
int argc;
char *argv[];
{
int i;
int st = 0;
char force = 0;
for (i = 1; i < argc; i++){
if (!strcmp(argv[i],"-f")){ /* -f flag = force */
force = 1;
continue;
}
cleanup_fname(argv[i]);
if (iswild(argv[i]) ||(mkdir(argv[i]) && !force)){
printf("Cannot make directory \"%s\"\n",argv[i]);
st = 1;
}
}
return st;
}
/* rename a file */
dorename(argc,argv)
int argc;
char *argv[];
{
cleanup_fname(argv[1]);
cleanup_fname(argv[2]);
if (iswild(argv[1]) || iswild(argv[2])){
printf("No wildcard file rename\n");
return 1;
}
if (rename(argv[1],argv[2])){
printf("Cannot rename \"%s\" to \"%s\"\n",argv[1],argv[2]);
return 1;
}
return 0;
}
/* remove directories */
dormdir(argc,argv)
int argc;
char *argv[];
{
return wildcard(argc,argv,dirremove,NULL);
}
/* type a file on the console */
/* number of lines can be given as second parameter, negative value */
/* will be taken as tail lines. */
dotype(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
int c;
int lines = 0;
cleanup_fname(argv[1]);
if (iswild(argv[1])){
printf("No wildcard file type\n");
return 1;
}
if (argc > 2)
if ((lines = atoi(argv[2])) == 0)
lines = -24;
if ((fp = fopen(argv[1],binmode[READ_BINARY])) == NULL){
printf(cantopen,argv[1]);
return 1;
}
if (lines < 0){ /* tail of file */
fseek(fp,0L,2); /* seek to EOF */
while (fseek(fp,-2L,1) != -1){ /* backup one character (+getc) */
if ((c = getc(fp)) == '\n'){
if (++lines == 0)
break; /* done enough, start printing */
#if (defined(MSDOS) || defined(ATARI_ST))
fseek(fp,-1L,1); /* seek past \r, too */
#endif
}
}
if (lines != 0) /* could not find so many? */
fseek(fp,0L,0); /* then do from start of file */
}
while ((c = getc(fp)) != EOF){ /* type the (head of the) file */
#if (defined(MSDOS) || defined(ATARI_ST))
if (c == '\r'){ /* it is a CR, probably CR/LF */
if ((c = getc(fp)) != '\n'){/* read next and verify it is LF */
ungetc(c,fp); /* no, put it back */
c = '\r'; /* and process the CR */
}
}
#endif
if (c >= ' ' || c == '\n' || c == '\r' || c == '\b' || c == '\t')
putchar(c);
else
putchar('.');
if (lines && c == '\n' && --lines == 0 && getc(fp) != EOF){
fclose(fp);
return 0;
}
}
printf("EOF\n");
fclose(fp);
return 0;
}
/* Create a directory listing in a temp file and return the resulting file
* descriptor. If full == 1, give a full listing; else return just a list
* of names.
*/
FILE *
dir(path,full)
char *path;
int full;
{
FILE *fp,*tmpfile();
if ((fp = tmpfile()) != NULLFILE) {
getdir(path,full,0,fp);
/* This should be rewind(), but Aztec doesn't have it */
fseek(fp,0L,0);
}
return fp;
}
/* wildcard filename lookup */
filedir(name,times,ret_str)
char *name;
int times;
char *ret_str;
{
register char *cp,*cp1;
static struct dirent sbuf;
#ifdef MSC
if (times == 0) {
if (_dos_findfirst(name,ST_HIDDEN|ST_DIRECT,&sbuf))
sbuf.fname[0] = '\0';
} else {
if (_dos_findnext(&sbuf))
sbuf.fname[0] = '\0';
}
#else
#ifdef __TURBOC__
if (times == 0) {
if (findfirst(name,&sbuf,ST_HIDDEN|ST_DIRECT))
sbuf.fname[0] = '\0';
} else {
if (findnext(&sbuf))
sbuf.fname[0] = '\0';
}
#el